﻿<?xml version="1.0" encoding="utf-8" ?>
<comments>
  <remarks>
	  <para>
	    AutoInputProtectionControl is a composite control that consists of an <see cref="System.Web.UI.WebControls.Image"/>, <see cref="TextBox"/>, two validators 
	    and some <see cref="Label"/> controls.  It can be added to any web form, user control or custom control to ensure that all form 
	    submissions originate from a person instead of a bot.
	  </para>
	  <para>
	    Validation is accomplished by displaying an image to the user that contains letters and/or numbers.  The user must enter the characters 
	    that they see into a text box before submitting the form.  If a bot attempts to submit a page that contains the AIP web control without 
	    entering the correct value, then <see cref="Page.IsValid"/> will be <paramref name="false"/> on the server and access to protected 
	    resources may be denied.
	  </para>
	  <para>
      A unique randomized image is generated for each request by the <see cref="AutoInputProtectionTextProvider"/> implementation and
      <see cref="AutoInputProtectionImageProvider"/> implementation that is configured as the default, and all of the
      <see cref="AutoInputProtectionFilterProvider"/> implementations that are configured are applied.
	    The default text, image and filter configurations are used throughout the entire web site for all occurrences of this control.
	  </para>
	  <para>
	    The <see cref="System.Web.UI.WebControls.Image.ImageUrl"/> property is automatically assigned to a special value that requests an image from the server using the 
	    AIP request handler.  The URL is generated internally by the control and consists of the base path specified by 
	    <see cref="AutoInputProtection.ImageRequestHandlerPath"/> and a query string that contains the public key created at the same time that 
	    the image is generated on the server.  The URL is unique to the current request and it may only be used once, by default.
	  </para>
	  <h4>Appearance</h4>
	  <para>
	    The appearance of this control can be fully customized by setting style properties and/or defining a custom <see cref="Template"/>.  
	    All text messages, including validator error messages, can be explicitly set via properties.
	  </para>
	  <para>
	    The following table shows the style properties that are supported by this control: 
	  </para>
	  <list type="table">
		  <listheader>
			  <term>Style property</term>
			  <description>UI element affected</description>
		  </listheader>
		  <item>
			  <term><see cref="ImageStyle"/></term>
			  <description><see cref="System.Web.UI.WebControls.Image"/> control.</description>
		  </item>
		  <item>
			  <term><see cref="TextBoxStyle"/></term>
			  <description>Text input field.</description>
		  </item>
		  <item>
			  <term><see cref="LabelTextStyle"/></term>
			  <description>Label for the text input field.</description>
		  </item>
		  <item>
			  <term><see cref="TitleTextStyle"/></term>
			  <description>Title text.</description>
		  </item>
		  <item>
			  <term><see cref="InstructionTextStyle"/></term>
			  <description>Text that provides instructions to the user.</description>
		  </item>
		  <item>
			  <term><see cref="ValidatorTextStyle"/></term>
			  <description>Text displayed when validation errors occur.</description>
		  </item>
	  </list>
	  <h4>Behavior</h4>
	  <para>
	    By default, AutoInputProtectionControl will generate tests that expire within a certain timeframe if they are not used.
	    The following properties can be set to change this behavior: 
	  </para>
	  <list type="table">
		  <listheader>
			  <term>Property</term>
			  <description>Behavior</description>
		  </listheader>
		  <item>
			  <term>RequestKeepAlive</term>
        <description>
          <include file="comments/autoinputprotectioncontrol.xml" path='//property[@name="RequestKeepAlive"]/remarks/*[@usage="true"]'/>
        </description>
		  </item>
		  <item>
			  <term>RequestTimeout</term>
        <description>
          <include file="comments/autoinputprotectioncontrol.xml" path='//property[@name="RequestTimeout"]/remarks/*[@usage="true"]'/>
        </description>
		  </item>
		  <item>
			  <term>ValidationKeepAlive</term>
        <description>
          <include file="comments/autoinputprotectioncontrol.xml" path='//property[@name="ValidationKeepAlive"]/remarks/*[@usage="true"]'/>
        </description>
		  </item>
		  <item>
			  <term>ValidationTimeout</term>
        <description>
          <include file="comments/autoinputprotectioncontrol.xml" path='//property[@name="ValidationTimeout"]/remarks/*[@usage="true"]'/>
        </description>
		  </item>
	  </list>
	  <h4>Validator Controls</h4>
	  <para>
	    A <see cref="RequiredFieldValidator"/> control is used to prevent users from submitting the form without first entering a value into 
	    the <see cref="TextBox"/> and a <see cref="CustomValidator"/> is used to supply the user's input to this control so that it may be 
	    validated.
	  </para>
	  <para>
	    Setting the <see cref="ValidationGroup"/> property of this control will set the <see cref="BaseValidator.ValidationGroup"/> properties of 
	    both validators to the same value automatically.  By default, <see cref="ValidationGroup"/> is not set on either validator control.
    </para>
	</remarks>
  
  <!-- ****************** Examples ****************** -->
  
  <example id="screenshots">
    <para>The following example uses the default appearance of <see cref="AutoInputProtectionControl"/> with the default provider configuration.</para>
    <include file="images.xml" path='//img[@id="Example-Default"]'/>
    <para>The following example uses a custom templated appearance of <see cref="AutoInputProtectionControl"/> with a custom provider configuration.</para>
    <include file="images.xml" path='//img[@id="Example-Blog"]'/>
  </example>
  <example id="1">
    <para>The following code example uses an <see cref="AutoInputProtectionControl"/> with the default settings.</para>
    <code><![CDATA[<%@ Page Language="C#" %>
<%@ Register TagPrefix="dsweb" Namespace="DaveSexton.Web.Controls" Assembly="DaveSexton.AutoInputProtection" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
  void Page_Load()
  {
    if (Page.IsPostBack)
    {
      Page.Validate();

      if (Page.IsValid)
        protectedResource.Visible = true;
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>AIP Example</title>
</head>
<body>
    <form id="form1" runat="server">
      <dsweb:AutoInputProtectionControl runat="server" ID="aip" />

      <asp:Button runat="server" ID="submitButton" Text="Submit" />
      
      <br /><asp:Label runat="server" ID="protectedResource" BackColor="Red" Visible="false">This is a protected resource.</asp:Label>
      
      <asp:ValidationSummary runat="server" ID="summary" />
    </form>
</body>
</html>]]></code>
  </example>
  <example id="2">
    <para>The following example uses an <see cref="AutoInputProtectionControl"/> with a custom template.</para>
    <para>
      The control's <see cref="RequestKeepAlive"/> property is set to <see langword="true"/> in case there is a long delay for the
      browser to request the image from the server.  The <see cref="ValidationKeepAlive"/> property is set to <see langword="true"/>
      so that the current test will never timeout before the user responds with an answer.
    </para>
    <code><![CDATA[<%@ Page Language="C#" %>
<%@ Register TagPrefix="dsweb" Namespace="DaveSexton.Web.Controls" Assembly="DaveSexton.AutoInputProtection" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
  void Page_Load()
  {
    if (Page.IsPostBack)
    {
      Page.Validate();

      if (Page.IsValid)
        protectedResource.Visible = true;
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>AIP Example</title>
</head>
<body>
    <form id="form1" runat="server">
      <dsweb:AutoInputProtectionControl runat="server" ID="aip" RequestKeepAlive="true" ValidationKeepAlive="true">
        <Template>
          <asp:Image runat="server" ID="Image" />
          <br />
          Enter the text from the image: <br />
          <asp:TextBox runat="server" ID="Text" />
          <asp:RequiredFieldValidator runat="server" ID="RequiredValidator" ControlToValidate="Text" Display="Dynamic" />
          <asp:CustomValidator runat="server" ID="Validator" ControlToValidate="Text" Display="Dynamic" />
        </Template>
      </dsweb:AutoInputProtectionControl>

      <asp:Button runat="server" ID="submitButton" Text="Submit" />
      
      <br /><asp:Label runat="server" ID="protectedResource" BackColor="Red" Visible="false">This is a protected resource.</asp:Label>
      
      <asp:ValidationSummary runat="server" ID="summary" />
    </form>
</body>
</html>]]></code>
  </example>
  
  <!-- ****************** Properties ****************** -->
  
  <property name="RequestKeepAlive">
    <remarks>
      <note>
        <see cref="RequestKeepAlive"/> is ignored when <see cref="AutoInputProtection.PersistenceMode"/> is set to <see cref="AutoInputProtectionPersistenceMode.Session"/>.
      </note>
      <note>
        The recommended value for <see cref="RequestKeepAlive"/> is <see langword="false"/>.
      </note>
      <para usage="true"><see cref="RequestKeepAlive"/> is <see langword="false"/> by default.</para>
      <para usage="true">
        You can set <see cref="RequestKeepAlive"/> to <see langword="true"/> if you want
        to use a sliding expiration for the image in the server cache; otherwise, the image will automatically expire when
        it's requested for the first time so that it cannot be used again.  The default value of <see langword="false"/>
        should be fine in most cases.  If you find that AIP images are repeatedly broken then consider increasing the value
        of the <see cref="RequestTimeout"/> property instead.  If that doesn't work, then consider a web page design that
        does not require a particular AIP image to be requested more than once by a browser.
      </para>
    </remarks>
  </property>
  <property name="RequestTimeout">
    <remarks>
      <note>
        <see cref="RequestTimeout"/> is ignored when <see cref="AutoInputProtection.PersistenceMode"/> is set to <see cref="AutoInputProtectionPersistenceMode.Session"/>.
      </note>
      <para usage="true">15 seconds is the default value.</para>
      <para usage="true">
        <see cref="RequestTimeout"/> is an initial timeout for the first request of an AIP image.  When <see cref="RequestKeepAlive"/> is <see langword="true"/>, 
        <see cref="RequestTimeout"/> also indicates a sliding expiration for subsequent requests of the same image.  It does not affect the amount of time a user has to 
        submit the form; its value only indicates the amount of time given to the client browser to request the image from the server.
      </para>
      <note>
        Images are removed from the server immediately when validation occurs so that subsequent requests will fail, regardless of whether a sliding expiration is used.
      </note>
      <para>
        When <see cref="RequestKeepAlive"/> is <see langword="false"/>, <see cref="RequestTimeout"/> is used as an absolute expiration.
      </para>
      <para usage="true">
        If you find that it typically takes longer than 15 seconds for a browser to request an AIP image from your server after the initial request 
        of the page that contains this control, then increase the value of <see cref="RequestTimeout"/> to a reasonable number of seconds to give 
        browsers more time.
      </para>
    </remarks>
  </property>
  <property name="ValidationKeepAlive">
    <remarks>
      <note>
        <see cref="ValidationKeepAlive"/> is ignored when <see cref="AutoInputProtection.PersistenceMode"/> is set to <see cref="AutoInputProtectionPersistenceMode.Session"/>.
      </note>
      <note>
        The recommended value for <see cref="ValidationKeepAlive"/> is <see langword="false"/>.
      </note>
      <para usage="true"><see cref="ValidationKeepAlive"/> is <see langword="false"/> by default.</para>
      <para>
        When <see cref="ValidationKeepAlive"/> is <see langword="false"/>, the challenge's text will be removed from the server when the timeout
        specified by <see cref="ValidationTimeout"/> expires so that the challenge cannot be used for subsequent requests.
      </para>
      <note>
        Challenges are removed from the server immediately when validation occurs so that subsequent requests will fail, regardless of whether <see cref="ValidationKeepAlive"/>
        is <see langword="false"/>.
      </note>
      <para>
        When <see cref="ValidationKeepAlive"/> is <see langword="true"/>, the challenge's text is not removed from the server until validation occurs.
      </para>
      <para usage="true">
        Set <see cref="ValidationKeepAlive"/> to <see langword="true"/> if you do
        not want to use a timeout for validation; otherwise, all tests use an absolute expiration that is the number of seconds
        specified by the <see cref="ValidationTimeout"/> property.  When using this control on a page with information that a user
        will read and/or form elements that a user will fill in before submitting the form, then setting <see cref="ValidationKeepAlive"/> to
        <see langword="true"/> will ensure that the user may validate the current request no matter how long they take to submit
        the form.  As a security precaution though it's recommended that you leave <see cref="ValidationKeepAlive"/> as <see langword="false"/> so
        that the timeout is used and move the control to a page where it exists alone so that users may respond in a timely manner.
        When using this control to prevent comment spam in blog posts and forums, for example, setting <see cref="ValidationKeepAlive"/> to
        <see langword="true"/> should be acceptable.  You can also increase security by configuring AIP to use
        <see cref="AutoInputProtectionUserMode.SessionOrClient"/> instead of the default value of <see cref="AutoInputProtectionUserMode.Client"/>,
        if sessions are enabled, since it's (arguably) harder to spoof a session cookie then it is to spoof a user address or name.
      </para>
      <!--warn about indefinite persistence:-->
      <include file='comments.xml' path='//note[@id="ValidationKeepAlive"]'/>
    </remarks>
  </property>
  <property name="ValidationTimeout">
    <remarks>
      <note>
        <see cref="ValidationTimeout"/> is ignored when <see cref="AutoInputProtection.PersistenceMode"/> is set to <see cref="AutoInputProtectionPersistenceMode.Session"/>.
      </note>
      <para usage="true">30 seconds is the default value.</para>
      <para usage="true"><see cref="ValidationTimeout"/> is ignored when <see cref="ValidationKeepAlive"/> is <see langword="true"/>.</para>
      <para usage="true">
        You can increase or decrease the value to better accomodate the control's usage on
        a given page.  If, for example, the control is being used by itself in a wizard step, you may be able to decrease the value to
        reduce the chances that a spoofed or hijacked session could be used to pass validation.  If the control is being used on a page
        where a user would typically wait to submit the form, such as when short reading material or one or two simple form elements
        exist, then you may be able to increase the value to ensure that users will be able to pass the current test.  On pages that
        have a lot of reading material or many input elements you may want to set <see cref="ValidationKeepAlive"/> to <see langword="true"/>
        instead.
      </para>
    </remarks>
  </property>
</comments>